package com.seek.util.authcheck;


import com.alibaba.fastjson.JSON;
import com.seek.authcheck.annotation.AuthRule;
import com.seek.authcheck.constants.AuthConstant;
import com.seek.model.authcheck.CarrierAuthModel;
import com.seek.model.entity.TAuthMetric;
import java.lang.reflect.Field;
import java.util.List;
import java.util.Map;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 自动认证工具类
 * Created by weh on 2017/7/2.
 */
public class AuthCheckUtils {

  private static final Logger logger = LoggerFactory.getLogger(AuthCheckUtils.class);

  public static TAuthMetric getAuthResult(Object object, String fieldName,
      Map<String, List<TAuthMetric>> ruleMap) throws Exception {
    Field field = object.getClass().getDeclaredField(fieldName);
    AuthRule annotation = field.getAnnotation(AuthRule.class);
    if (null != annotation) {
      field.setAccessible(true);
      String vaule = null != field.get(object) ? field.get(object).toString() : "";
      String key = annotation.authProduct() + "#" + annotation.authDimension();
      String extendFields = annotation.extendFiled();
      String desc = annotation.desc();
      String remark = "";
      if (StringUtils.isNotEmpty(extendFields)) {
        Field remarkFiled = object.getClass().getDeclaredField(extendFields);
        remarkFiled.setAccessible(true);
        remark = remarkFiled.get(object).toString();
      }

      return getRule(vaule, desc, remark, ruleMap.get(key));
    }

    return null;
  }

  public static TAuthMetric getCallMatchesCheck(CarrierAuthModel model,
      Map<String, List<TAuthMetric>> ruleMap) {

    String key = "CARRIER#CALL_MATCH";
    List<TAuthMetric> rules = ruleMap.get(key);
    if (CollectionUtils.isEmpty(rules)) {
      return null;
    }
    for (TAuthMetric rule : rules) {
      if (phoneCountcheck(model.getPhoneCount(), null, rule)) {
        rule.setDesc("通讯录匹配度");
        logger.info("通讯录匹配到电话数:{}", JSON.toJSONString(rule));
        logger.info("matches:{}", JSON.toJSONString(model.getCallMatches()));
        rule.setValue(Double.valueOf(model.getCallMatches()) * 100 + "%");
        if (rule.getAuthPass() == AuthConstant.CHECK_SUCCESS) {
          if (checkMatches(model.getCallMatches(), rule)) {
            rule.setAuthPass(AuthConstant.CHECK_SUCCESS);
          } else {
            rule.setAuthPass(AuthConstant.CHECK_FAIL);
          }
        }
        return rule;
      }
    }
    return null;
  }

  private static TAuthMetric getRule(String value, String desc, String remark,
      List<TAuthMetric> rules) {
    if (CollectionUtils.isEmpty(rules)) {
      return null;
    }
    for (TAuthMetric rule : rules) {
      if (check(value, remark, rule)) {
        rule.setDesc(desc);
        rule.setValue(value);
        return rule;
      }
    }
    return null;
  }

  private static boolean check(String value, String remark, TAuthMetric rule) {
//    System.out.println(value);
    if (StringUtils.isNotEmpty(value) && (!StringUtils.equals("null", value))&& (!StringUtils.equals("DEFAULT", rule.getMinMetric()))) {
      double val = Double.valueOf(value);
      double minValue = Double.valueOf(rule.getMinMetric());
      if (StringUtils.isEmpty(rule.getMaxMetric())) {
        return val >= minValue && StringUtils.equals(remark, rule.getRemark());
      } else {
        double maxValue = Double.valueOf(rule.getMaxMetric());
        return val >= minValue && val <= maxValue && StringUtils.equals(remark, rule.getRemark());
      }
    } else {
      return StringUtils.equals(rule.getMinMetric(), "DEFAULT");
    }
  }

  private static boolean phoneCountcheck(String value, String remark, TAuthMetric rule) {
//    System.out.println(value);
    if (StringUtils.isNotEmpty(value) && (!StringUtils.equals("null", value))&& (!StringUtils.equals("DEFAULT", rule.getMinMetric()))) {
      double val = Double.valueOf(value);
      double minValue = Double.valueOf(rule.getMinMetric());
      if (StringUtils.isEmpty(rule.getMaxMetric())) {
        return val >= minValue && StringUtils.equals(remark, rule.getRemark());
      } else {
        double maxValue = Double.valueOf(rule.getMaxMetric());
        return val >= minValue && val <= maxValue;
      }
    } else {
      return StringUtils.equals(rule.getMinMetric(), "DEFAULT");
    }
  }

  public static boolean checkMatches(String remark, TAuthMetric rule) {
    double remarkVal = 0;
    double ruleRemark = 0;
    if (StringUtils.isNotEmpty(remark)) {
      remarkVal = Double.valueOf(remark);
    }
    if (StringUtils.isNotEmpty(rule.getRemark())) {
      ruleRemark = Double.valueOf(rule.getRemark());
    }
    logger.info("remarkVal:{}, ruleRemark:{}", remarkVal, ruleRemark);

    return remarkVal >= ruleRemark;
  }

}
